package com.wan.core.event;

import com.wan.thread.actor.Actor;
import com.wan.thread.actor.IAsync;
import net.sf.cglib.reflect.FastMethod;

import java.lang.reflect.InvocationTargetException;

public class Listener {
    /** 源对象 */
    private final Object obj;
    /** 方法访问器 */
    private final FastMethod fastMethod;
    /** 是否强制异步 */
    private final boolean async;

    public Listener(Object obj, FastMethod fastMethod, boolean async) {
        this.obj = obj;
        this.fastMethod = fastMethod;
        this.async = async;
    }

    public Object getObj() {
        return obj;
    }

    public FastMethod getFastMethod() {
        return fastMethod;
    }

    public boolean isAsync() {
        return async;
    }

    public void call(Event event) throws InvocationTargetException {
        this.fastMethod.invoke(obj,new Object[]{event});
    }

    public Runnable toActor(Event event){
        if(event.asyncId() == 0){
            return () -> {
                try {
                    fastMethod.invoke(obj,new Object[]{event});
                } catch (InvocationTargetException e) {
                    throw new RuntimeException(e);
                }
            };
        }
        return new Actor() {
            @Override
            public long asyncId() {
                return event.asyncId();
            }

            @Override
            public void run() {
                try {
                    fastMethod.invoke(obj,new Object[]{event});
                } catch (InvocationTargetException e) {
                    throw new RuntimeException(e);
                }
            }
        };
    }
}
